home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
NeXTSTEP 3.1 (Developer) [x86]
/
NeXT Step 3.1 Intel dev.cdr.dmg
/
NextDeveloper
/
Examples
/
SoundAndMusic
/
SoundKit
/
SoundEditor
/
SoundDocument.m
< prev
next >
Wrap
Text File
|
1992-03-27
|
6KB
|
296 lines
/*
* You may freely copy, distribute and reuse the code in this example.
* NeXT disclaims any warranty of any kind, expressed or implied, as to
* its fitness for any particular use.
*/
#import "SoundDocument.h"
#import "SoundController.h"
#import "ScrollingSound.h"
#import <soundkit/soundkit.h>
#import <appkit/Application.h>
#import <appkit/Window.h>
#import <appkit/Panel.h>
#import <appkit/Cursor.h>
#import <stdlib.h>
#import <string.h>
#import <objc/NXStringTable.h>
extern int access();
@implementation SoundDocument
static void newLocation(NXPoint *p)
{
static count = 0;
p->x += (20.0 * count);
p->y -= (25.0 * count);
count = (count > 10)? 0 : count+1;
}
- init
{
NXRect theFrame;
[super init];
[NXApp loadNibSection:"SoundDocument.nib" owner:self];
[window setDelegate:self];
[window getFrame:&theFrame];
newLocation(&theFrame.origin);
[window moveTo:theFrame.origin.x :theFrame.origin.y];
[window makeKeyAndOrderFront:nil];
mySoundView = [view docView]; /* view is the ScrollingSound
in the nib file */
[mySoundView setSound:[[Sound alloc] init]];
return self;
}
- setFileName:(char *)aName
{
if (fileName)
free(fileName);
fileName = (char *)malloc(strlen(aName)+1);
strcpy(fileName,aName);
[window setTitleAsFilename:fileName];
return self;
}
- (char *)fileName
{
return fileName;
}
- sound
{
return [mySoundView sound];
}
- saveError:(const char *)msg arg: (char *)arg;
{
if (!stringTable)
stringTable = [[NXApp delegate] stringTable];
NXRunAlertPanel([stringTable valueForStringKey:"Save"],
[stringTable valueForStringKey:msg],
[stringTable valueForStringKey:"OK"],
NULL,NULL,arg);
return nil;
}
- saveToFormat:templateSound fileName:(char *)fn
{
if (fn) {
int err;
id theSound = [[mySoundView sound] copy];
if (templateSound && theSound) {
[theSound copySound:theSound];
err = [theSound convertToFormat:[templateSound dataFormat]
samplingRate:[templateSound samplingRate]
channelCount:[templateSound channelCount]];
if (err) {
/* The DSP is required for compression or decompression */
return [self saveError:
"Cannot do format conversion %s (DSP busy?)" arg:""];
}
}
if (!access(fn, 0)) { /* file exists */
char fileBuf[1024];
strcpy(fileBuf,fn);
strcat(fileBuf,"~");
rename(fn,fileBuf);
}
err = [theSound writeSoundfile:fn];
if (err) {
return [self saveError:"Cannot write %s" arg:fn];
}
else
[window setDocEdited:NO];
[theSound free];
}
return self;
}
- save:sender
{
return [self saveToFormat:nil fileName:fileName];
}
- load:sender
{
if (fileName) {
id newSound, oldSound = [mySoundView sound];
newSound = [[Sound alloc] initFromSoundfile:fileName];
if (newSound) {
if (![mySoundView setSound:newSound]) { /* not displayable */
if ([newSound convertToFormat:SND_FORMAT_LINEAR_16]) {
if (!stringTable)
stringTable = [[NXApp delegate] stringTable];
NXRunAlertPanel([stringTable valueForStringKey:"Open"],
[stringTable valueForStringKey:
"Cannot convert format for display "
"(DSP busy?)"],
[stringTable valueForStringKey:"OK"],
NULL,NULL);
return nil;
} else
[mySoundView setSound:newSound];
}
[oldSound free];
}
}
[window setDocEdited:NO];
return self;
}
- revertToSaved:sender
{
if([window isDocEdited] && fileName
&& strcmp(strrchr (fileName,'/'),"/UNTITLED")) {
if (!stringTable)
stringTable = [[NXApp delegate] stringTable];
if (NXRunAlertPanel([stringTable valueForStringKey:"Revert"],
[stringTable valueForStringKey:"Revert to saved version"
" of %s?"],
[stringTable valueForStringKey:"Revert"],
[stringTable valueForStringKey:"Cancel"],
0,fileName) == NX_ALERTDEFAULT)
[self load:nil];
}
return self;
}
- play:sender
{
[mySoundView play:sender];
return self;
}
- stop:sender
{
[mySoundView stop:sender];
return self;
}
- pause:sender
{
[mySoundView pause:sender];
return self;
}
- resume:sender
{
[mySoundView resume:sender];
return self;
}
- record:sender
{
[mySoundView record:sender];
[window setDocEdited:YES];
return self;
}
- touch
{
[window setDocEdited:YES];
return self;
}
- setDelegate:anObject
{
[mySoundView setDelegate:anObject];
return self;
}
- windowDidBecomeMain:sender
{
[[NXApp delegate] setDocument:self];
[window makeFirstResponder:mySoundView];
[mySoundView showCursor];
return self;
}
- windowDidResignMain:sender
{
id theController = [NXApp delegate];
if ([theController document] == self)
[theController setDocument:nil];
[mySoundView hideCursor];
return self;
}
- windowDidMiniaturize:sender
{
[mySoundView stop:sender];
[mySoundView hideCursor];
return self;
}
- windowWillClose:sender
{
int choice;
if ([window isDocEdited]) {
if (!stringTable)
stringTable = [[NXApp delegate] stringTable];
choice = NXRunAlertPanel([stringTable valueForStringKey:"Close"],
[stringTable valueForStringKey:"Sound is modified.\nSave it?"],
[stringTable valueForStringKey:"Yes"],
[stringTable valueForStringKey:"No"],
[stringTable valueForStringKey:"Cancel"]);
switch (choice) {
case NX_ALERTALTERNATE:
break;
case NX_ALERTDEFAULT:
[[NXApp delegate] save:nil];
break;
case NX_ALERTOTHER:
return nil;
}
}
[self windowDidResignMain:nil];
[window setDelegate:nil];
[self free];
return sender;
}
static int calcFormat(SNDSoundStruct *s)
{
if (s->dataFormat == SND_FORMAT_MULAW_8)
return SND_FORMAT_MULAW_8;
else if (s->dataFormat == SND_FORMAT_INDIRECT) {
SNDSoundStruct **iBlock = (SNDSoundStruct **)s->dataLocation;
if (*iBlock)
return (*iBlock)->dataFormat;
else
return SND_FORMAT_UNSPECIFIED;
} else
return s->dataFormat;
}
- (BOOL)isRecordable
{
int format;
id theSound = [mySoundView sound];
SNDSoundStruct *soundStruct = [theSound soundStruct];
if (!soundStruct) return YES;
format = calcFormat(soundStruct);
if (format == SND_FORMAT_MULAW_8 &&
soundStruct->samplingRate == (int)SND_RATE_CODEC &&
soundStruct->channelCount == 1 )
return YES;
else
return NO;
}
- (BOOL) isPlayable
{
return [mySoundView isPlayable];
}
@end